/**
 * Copyright (c) 2012 Sean Beecroft, Permission is hereby granted, free of
 * charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy, modify,
 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * For more information on this project and others, please visit my google code 
 * repository:
 * https://code.google.com/u/seanbeecroft@gmail.com/
 */
package javaballs;

import java.awt.Color;
import java.util.ArrayList;

public class Ball {

    private double x = 0;
    private double y = 0;
    private double vy = 0;
    private double vx = 0;
    private int width = 10;
    private double mass = 10;
    private Color color = Color.green;
    public volatile boolean collision = false;

    @Override
    public String toString() {
        return "" + getVy();
    }
    
    public void hit(Ball b) {

        if (b != this && !collision  ) {
            double dx = x - b.x;
            double dy = y - b.y;

            double ca = Math.atan2(dy, dx);

            double speed1 = Math.sqrt(vx * vx + vy * vy);
            double speed2 = Math.sqrt(b.vx * b.vx + b.vy * b.vy);

            double direction1 = Math.atan2(vy, vx);
            double direction2 = Math.atan2(b.vy, b.vx);

            double vx_1 = speed1 * Math.cos(direction1 - ca);
            double vy_1 = speed1 * Math.sin(direction1 - ca);
            double vx_2 = speed2 * Math.cos(direction2 - ca);
            double vy_2 = speed2 * Math.sin(direction2 - ca);

            double final_vx_1 = ((mass - mass) * vx_1 + (b.mass + b.mass) * vx_2) / (mass + b.mass);
            double final_vx_2 = ((mass + mass) * vx_1 + (b.mass - mass) * vx_2) / (mass + b.mass);

            //Not change because this is an 1D environment collision.

            double final_vy_1 = ((mass - mass) * vy_1 + (b.mass + b.mass) * vy_2) / (mass + b.mass);
            double final_vy_2 = ((mass + mass) * vy_1 + (b.mass - mass) * vy_2) / (mass + b.mass);

            
            //final_vy_1 -= 0.001;
            //final_vy_2 -= 0.001;
            //final_vx_1 -= 0.001;
            //final_vx_2 -= 0.001;

            vx = Math.cos(ca) * final_vx_1 + Math.cos(ca + Math.PI / 2) * final_vy_1;
            vy = Math.sin(ca) * final_vx_1 + Math.sin(ca + Math.PI / 2) * final_vy_1;
            b.vx = Math.cos(ca) * final_vx_2 + Math.cos(ca + Math.PI / 2) * final_vy_2;
            b.vy = Math.sin(ca) * final_vx_2 + Math.sin(ca + Math.PI / 2) * final_vy_2;


            //System.out.println("Balls hit");
            //System.out.println(b.vx);
            //System.out.println(b.vy);
            //System.out.println(vx);
            //System.out.println(vy);

        }
    }

    public boolean isTouchingAnything() {
        boolean ret =  getCollisions().size() > 0;
        return ret;
    }

    public ArrayList<Ball> getCollisions() {
        ArrayList<Ball> c = new ArrayList<Ball>();
        ArrayList<Ball> v = Main.getBalls();
        for (int i = 0; i < v.size(); i++) {
            Ball m = (Ball) v.get(i);
            if( m != null ){
                if (this != m) {
                    if (this.isCollision(m)) {
                        c.add(m);
                    }
                }
            }
        }
        return c;
    }

    boolean isCollision(Ball b2) {
        if (this == b2 || b2 == null ) {
            // you can't collide with yourself or a null ball!
            return false;
        }
        // already collided.

        double wx = (x + (width / 2)) - (b2.x + (b2.width / 2));
        double wy = (y + (width / 2)) - (b2.y + (b2.width / 2));

        //we calculate the distance between the centers two
        //colliding balls (theorem of Pythagoras)
        double distance = Math.sqrt(wx * wx + wy * wy);

        if (distance < ((width/2)+(b2.width/2))) {
            //collision = true;
            return true;
        }
        return false;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public double getVy() {
        return vy;
    }

    public void setVy(double vy) {
        this.vy = vy;
    }

    public double getVx() {
        return vx;
    }

    public void setVx(double vx) {
        this.vx = vx;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public double getMass() {
        return mass;
    }

    public void setMass(double mass) {
        this.mass = mass;
    }
}
